home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- *
- * T O K E N . C
- * -------------
- *
- * Description:
- * Reads tokens from input file. Tokens are the C-stype tokens. It is
- * allso possible to unget tokens for later recall by GetTok().
- *
- * Included functions:
- * GetTok() - Get token
- *
- *
- * Revision:
- * Ver Date By Reason
- * --- ---- -- ------
- * 1.00 900619 Lars Berntzon Created
- *
- ******************************************************************************/
- #ifndef lint
- static volatile char sccs_id[] = "@(#) token.c,v 1.6 1993/05/13 21:55:48 lasse Exp";
- #endif
-
- #include "config.h"
- #include "token.h"
-
- #define isnormal(c) (isalnum(c) || (c) == '_')
-
- /* T y p e s */
- typedef enum { st_init,
- st_normal,
- st_searching_quote,
- st_got_slash,
- st_got_comment,
- st_got_star,
- st_searching_endcomment,
- st_got_backslash } state_t;
-
- /* G l o b a l v a r i a b l e s */
-
- int line = 1; /* Current line number */
- FILE *in; /* The input file pointer */
-
- /* L o c a l v a r i a b l e */
-
- static int ch = 0; /* Next input character */
-
-
- /*******************************************************************************
- *
- * G E T O K
- * ---------
- *
- * Description:
- * Reads one token from input file (skips c type comments).
- *
- * Output:
- * ret_token - String where data wil be put (if not NULL).
- * ret_space - Space string found before token (if not NULL).
- *
- * Return:
- * String containing token, NULL if end of file.
- *
- ******************************************************************************/
- char *
- GetTok(char *ret_token, char *ret_space)
- {
- static char token[TOKENSIZE]; /* Where read token is stored */
- static char space[TOKENSIZE]; /* Where spaces before token is stored */
- int token_pos = 0; /* Current token write position */
- int space_pos = 0; /* Current space positions */
- state_t state = st_init; /* Current state */
-
- /*
- * Read first char of file.
- */
- if (ch == 0) {
- ch = getc(in);
- }
-
- if (ch == EOF) return NULL;
-
- for(; ch != EOF; ch = getc(in))
- {
- if (ch == '\n')
- {
- line++;
- }
-
- switch(state)
- {
- case st_init:
- if (isspace(ch)) {
- space[space_pos++] = ch;
- break;
- }
- else if (ch == '"') {
- token[token_pos++] = ch;
- state = st_searching_quote;
- }
- else if (ch == '/') {
- token[token_pos++] = ch;
- state = st_got_slash;
- }
- else if (!isnormal(ch)) {
- token[token_pos++] = ch;
- token[token_pos++] = 0;
- ch = 0;
- goto found;
- }
- else if (isnormal(ch)) {
- token[token_pos++] = ch;
- state = st_normal;
- }
- break;
-
- case st_normal:
- if (isnormal(ch)) {
- token[token_pos++] = ch;
- }
- else {
- token[token_pos++] = 0;
- goto found;
- }
- break;
-
- case st_searching_quote:
- token[token_pos++] = ch;
- if (ch == '\\') {
- state = st_got_backslash;
- }
- else {
- if (ch == '"') {
- token[token_pos++] = 0;
- ch = 0;
- goto found;
- }
- }
- break;
-
- case st_got_backslash:
- token[token_pos++] = ch;
- state = st_searching_quote;
- break;
-
- case st_got_slash:
- if (ch == '*') {
- state = st_got_comment;
-
- /*
- * Remove the slash from token.
- */
- token_pos--;
-
- /*
- * And save the comment in the space field instead.
- */
- space[space_pos++] = '/';
- space[space_pos++] = '*';
-
- }
- else {
- goto found;
- }
- break;
-
- case st_got_comment:
- if(ch == '*') {
- state = st_got_star;
- }
- space[space_pos++] = ch;
- break;
-
- case st_got_star:
- space[space_pos++] = ch;
- if (ch == '/') {
- state = st_init;
- }
- else if (ch != '*') {
- state = st_got_comment;
- }
- break;
-
- default:
- fprintf(stderr, "unknown state in file %s line %d, this should not happen\n",
- __FILE__, __LINE__);
- }
- }
-
- found:
- space[space_pos] = 0;
- token[token_pos] = 0;
-
- if(ret_space) {
- strcpy(ret_space, space);
- }
-
- if (ret_token) {
- strcpy(ret_token, token);
- }
- else {
- ret_token = token;
- }
-
- if (token_pos == 0) return NULL;
-
- return ret_token;
- }
-
- /*******************************************************************************
- *
- * O P E N T O K
- * -------------
- *
- * Description:
- * Open a file to read tokens from.
- *
- * Input:
- * name - Name of file.
- *
- * Return:
- * Opened files pointer, of NULL if failure.
- *
- ******************************************************************************/
- FILE *OpenTok(char *name)
- {
- if (in != NULL) {
- fclose(in);
- ch = 0;
- }
- return in = fopen(name, "r");
- }
-
- #ifdef STANDALONE
- /*******************************************************************************
- *
- * M A I N
- * -------
- *
- * Description:
- * Main routine when compiled as standalone.
- * This is only used for test.
- *
- ******************************************************************************/
-
- main()
- {
- char token[TOKENSIZE];
- char space[TOKENSIZE];
- char outstr[1000];
- char *p;
-
- in = stdin;
-
- while(GetTok(token, space))
- {
- sprintf(outstr, "'%s'-'%s'-%d", token, space, line);
- for(p = outstr; *p != NULL; p++)
- {
- switch (*p)
- {
- case '\n':
- putchar('\\');
- putchar('n');
- break;
-
- case '\t':
- putchar('\\');
- putchar('t');
- break;
-
- default:
- putchar(*p);
- }
- }
- putchar('\n');
- }
- }
- #endif /* STANDALONE */
-